

;;
;; sample code
(defparameter *v*
  '(
    (if (== (mod t0 2) 0)
	;; else
	(printf "t0 is even")
	;; then
	(printf "t0 is odd"))
    
    (module "module-1"
     (marker m1 null)			; nullifies it's content by default
     (marker m2 as-is)			; leaves content as it is

     (func f1 (a1 a2 a3)
      (m2
       (let (a (b 12))
	 (set a 50)
	 (m2 (debug-print a b))
	 (+ a b))))
     )					; end of module-1
    ))

(defparameter *v-flow*
  '(
    (flow-sample 1
     (0 enter-scope a)
     (1 set a 10)
     (2 return a)
     )					; end of flow-sample-1


    ;; `if' marker: condition-expression then-expression else-expression
    (flow-sample 2

     ;; if expression marker
     (marker if (cond-expr then-expr else-expr)
      (let ((cond-ret (gen-var "condition" "result"))
	    (result (get-result-sink)))

	;; generate flow
	(create-flow
	 (nil enter-scope cond-ret)
	 (nil set cond-ret cond-expr)
	 (nil if cond-ret (then 'then-label) (else 'else-label))
	 ('then-label set result then-expr)
	 (nil goto 'end-if)
	 ('else-label set result else-expr)
	 ('end-if leave-scope cond-ret)))))

    ;; TODO: transform to C
    (flow-sample 3
     (create-flow
      (enter-scope cond-ret)
      (set cond-ret cond-expr)

      (if expr
	  ;; then block
	  (sequence
	   (nop 1)
	   (nop 2))
	  ;; else block
	  (sequence
	   (nop 3)
	   (nop 4)))

      (label do-loop-enter)
      (test cond-ret)
      (goto do-loop-enter)))

    ;; `as-is' flow expression marker
    (flow-sample "as-is flow expression marker"

     ;; as-is
     (marker as-is (&rest expressions)
      (let ((result (get-result-sink))
	    (flow (create-flow)))
	(loop for expr in expressions do
	     (add-flow-steps (nil eval expr)))
	flow)))

    ))


;;
;; accepts source list and constructs list that contains
;; of a pairs:
;; (notlast ELEM1) (notlast ELEM2) .. (notlast ELEM(N-1)) (last ELEMN)
;;
(defun last-aware-convert (source-list)
  (check-type source-list list)
  (let (target-list)
    (do (next (it source-list))
	((null it))
      (setf next (cdr it))
      (setf target-list
	    (append target-list
		    (list (list (if next 'notlast 'last) (car it)))))
      (setf it next))
    target-list))

;; (last-aware-convert '(a b c dd))

